package com.xqboss.apps.service.consumer;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.xqboss.apps.constant.Config;
import com.xqboss.apps.constant.LockKey;
import com.xqboss.apps.domain.consumer.*;
import com.xqboss.apps.domain.equipment.Equipment;
import com.xqboss.apps.domain.punch.PunchUserConfig;
import com.xqboss.apps.dto.consumer.ConsumerTeamDelDto;
import com.xqboss.apps.dto.consumer.ConsumerTeamDto;
import com.xqboss.apps.dto.consumer.ConsumerTeamMsgRecordDto;
import com.xqboss.apps.enums.consumer.*;
import com.xqboss.apps.enums.user.UserWalletEnum;
import com.xqboss.apps.enums.user.WalletChangeTypeEnum;
import com.xqboss.apps.mapper.consumer.ConsumerTeamMapper;
import com.xqboss.apps.mapper.consumer.ConsumerTeamMemberMapper;
import com.xqboss.apps.mapper.consumer.ConsumerUpvoteRecordMapper;
import com.xqboss.apps.mapper.consumer.ConsumerWarnPunchRecordMapper;
import com.xqboss.apps.service.equipment.EquipmentService;
import com.xqboss.apps.service.msg.PushService;
import com.xqboss.apps.service.punch.PunchUserConfigService;
import com.xqboss.apps.service.punch.PunchUserRecordService;
import com.xqboss.apps.service.punch.UserPunchService;
import com.xqboss.apps.service.user.SysUserWalletService;
import com.xqboss.apps.vo.consumer.*;
import com.xqboss.apps.vo.punch.TeamPunchRecordVo;
import com.xqboss.apps.vo.sys.SysUserVo;
import com.xqboss.common.constant.CacheConstants;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.core.domain.entity.SysUser;
import com.xqboss.common.core.redis.RedisCache;
import com.xqboss.common.core.redis.lock.RedisLock;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.LocalDateUtils;
import com.xqboss.common.utils.SecurityUtils;
import com.xqboss.common.utils.SocketUtil;
import com.xqboss.common.utils.StringUtils;
import com.xqboss.system.service.ISysConfigService;
import com.xqboss.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 队伍Service业务层处理
 *
 * @author xqboss
 * @date 2023-08-15
 */
@Service
public class ConsumerTeamService extends ServiceImpl<ConsumerTeamMapper, ConsumerTeam> {

    @Resource
    private ConsumerTeamMapper consumerTeamMapper;
    @Resource
    private ConsumerTeamMemberMapper consumerTeamMemberMapper;
    @Resource
    private ConsumerTeamMemberService consumerTeamMemberService;
    @Resource
    private ConsumerFriendsService consumerFriendsService;
    @Resource
    private SysUserWalletService sysUserWalletService;
    @Resource
    private ConsumerWarnPunchRecordMapper consumerWarnPunchRecordMapper;
    @Resource
    private ConsumerUpvoteRecordMapper consumerUpvoteRecordMapper;
    @Resource
    private ConsumerTeamMsgRecordService consumerTeamMsgRecordService;
    @Autowired
    private RedisCache redisCache;
    @Resource
    private ConsumerTeamApplyService consumerTeamApplyService;

    @Autowired
    private PunchUserRecordService userRecordService;

    @Autowired
    private ConsumerTeamGainRuleService teamGainRuleService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private ConsumerInteractMsgService consumerInteractMsgService;

    @Autowired
    @Lazy
    private TeamPunchStatService teamPunchStatService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    @Lazy
    private PushService pushService;

    @Autowired
    @Lazy
    private PunchUserRecordService punchUserRecordService;

    @Autowired
    private PunchUserConfigService punchUserConfigService;

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private UserPunchService userPunchService;


    /**
     * 查询队伍
     *
     * @return 队伍
     */
    public ConsumerTeamInfoVo selectConsumerTeamById(Integer teamId, Long userId) {
        ConsumerTeamInfoVo vo = consumerTeamMapper.getTeamMember(teamId);
        BigDecimal memberGain = vo.getMemberGain();//打卡增益%
        List<SysUserVo> voTeamMember = vo.getTeamMember();
        if (CollUtil.isNotEmpty(voTeamMember)) {
            voTeamMember.forEach(item -> {
                if (ObjUtil.isNotNull(item.getPunchIntegral())) {
                    item.setGainValue(item.getPunchIntegral().multiply(memberGain));
                }
            });
//            vo.setTotalPunch(vo.getTeamMember().stream().mapToInt(SysUserVo::getTotalPunch).sum());
            //成员打卡收益倒序
            voTeamMember = voTeamMember.stream().sorted(Comparator.nullsFirst(Comparator.comparing(SysUserVo::getPunchIntegral, Comparator.nullsFirst(BigDecimal::compareTo)).reversed()))
                    .collect(Collectors.toList());
        }
        //队伍上限
        vo.setIncomeMax(sysConfigService.getValue(Config.Sys.Punch.队伍增益上限));
        vo.setPunchMax(sysConfigService.getValue(Config.Sys.Punch.队伍打卡次数上限));
        vo.setPunchIncomeMax(sysConfigService.getValue(Config.Sys.Punch.队伍打卡收益上限));
        vo.setTeamGain(memberGain);
        vo.setTeamMember(voTeamMember);
        return vo;
    }

    /**
     * 查询队伍列表
     *
     * @param consumerTeam 队伍
     * @return 队伍
     */
    public List<ConsumerTeam> selectConsumerTeamList(ConsumerTeam consumerTeam) {
        return consumerTeamMapper.selectConsumerTeamList(consumerTeam);
    }

    /**
     * 新增队伍
     *
     * @param consumerTeamDTO 队伍
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean insertConsumerTeam(ConsumerTeamDto consumerTeamDTO) {
        ConsumerTeam consumerTeam = BeanUtil.copyProperties(consumerTeamDTO, ConsumerTeam.class);
        consumerTeam.setCreateTime(LocalDateUtils.getCurrentLocalDateTime());
        consumerTeam.setMemberCount(1);
        consumerTeam.setMaxNumber(10);//暂时写死
        LambdaQueryWrapper<ConsumerTeamMember> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ConsumerTeamMember::getUserId, consumerTeamDTO.getCreateUserId());
//        wrapper.eq("type", consumerTeamDTO.getType());
        ConsumerTeamMember one = consumerTeamMemberService.getOne(wrapper);
        if (ObjUtil.isNotNull(one)) {
            throw new ServiceException("已经有队伍了，不能再创建了~");
        }
        consumerTeamMapper.insertConsumerTeam(consumerTeam);

        //队伍成员
        ConsumerTeamMember teamMember = new ConsumerTeamMember();
        teamMember.setTeamId(consumerTeam.getId());
        teamMember.setUserId(consumerTeam.getCreateUserId());
        teamMember.setRole(ConsumerTeamRoleEnum.ADMINISTRATOR.getValue());
        teamMember.setJoinTime(LocalDateUtils.getCurrentLocalDateTime());
        teamMember.setIsCheck(1);
        //队伍消息记录已读位置id
        teamMember.setTeamMsgId(consumerTeamMsgRecordService.findLastId());
        boolean b = consumerTeamMemberService.save(teamMember);
//        int i = consumerTeamMemberMapper.insertConsumerTeamMember(teamMember);

        //创建队伍消息
        ConsumerTeamMsgRecord msgRecord = new ConsumerTeamMsgRecord();
        msgRecord.setType(ConsumerMsgRecordEnum.ADMINISTRATOR_ALTER.getValue());
        msgRecord.setTeamId(consumerTeam.getId());
        msgRecord.setFromUserId(consumerTeam.getCreateUserId());
        msgRecord.setToUserId(consumerTeam.getCreateUserId());
        msgRecord.setContent(SecurityUtils.getNickName() + "创建了队伍~");
        msgRecord.setSourceId(Long.valueOf(teamMember.getId()));
        consumerTeamMsgRecordService.save(msgRecord);
        return b;
    }

    /**
     * 修改队伍
     *
     * @param consumerTeam 队伍
     * @return 结果
     */
    public R updateConsumerTeam(ConsumerTeamDto consumerTeam) {
        //查询操作人有无编辑权限
        ConsumerTeamMember teamMember = consumerTeamMemberService.getOne(new LambdaQueryWrapper<ConsumerTeamMember>()
                .eq(ConsumerTeamMember::getTeamId, consumerTeam.getId())
                .eq(ConsumerTeamMember::getUserId, SecurityUtils.getUserId()));
        if (!teamMember.getRole().equals(ConsumerTeamRoleEnum.ADMINISTRATOR.getValue())) {
            return R.fail("无权限修改");
        }

        ConsumerTeam team = BeanUtil.copyProperties(consumerTeam, ConsumerTeam.class);
        team.setUpdateTime(LocalDateUtils.getCurrentLocalDateTime());
        int i = consumerTeamMapper.updateConsumerTeam(team);
        if (i != 1) {
            throw new ServiceException("修改队伍失败");
        }
        return R.ok();
    }

    /**
     * 批量删除队伍
     *
     * @param ids 需要删除的队伍主键
     * @return 结果
     */
    public int deleteConsumerTeamByIds(Long[] ids) {
        return consumerTeamMapper.deleteConsumerTeamByIds(ids);
    }

    /**
     * 删除队伍信息
     *
     * @param id 队伍主键
     * @return 结果
     */
    public int deleteConsumerTeamById(Long id) {
        return consumerTeamMapper.deleteConsumerTeamById(id);
    }

    public R<List<ConsumerTeamVo>> topList(ConsumerTeamDto dto) {
        List<Long> userIds = friendIdsList(dto);
        userIds.add(dto.getUserId());
        //设置当前登录用户是否在对应队伍中
        ConsumerTeamMember teamMember = consumerTeamMemberService.lambdaQuery().select(ConsumerTeamMember::getTeamId).eq(ConsumerTeamMember::getUserId, dto.getUserId()).one();
        Integer myTeamId = ObjUtil.isNotEmpty(teamMember)?teamMember.getTeamId():0;
        List<ConsumerTeamVo> list = consumerTeamMemberMapper.topList(userIds,myTeamId);
        if (CollUtil.isNotEmpty(list)) {
            /**
             *  先按a倒序排列、再按b倒序排列、最后按c正序排列
             *  list.sort(Comparator.comparing(SortTest::getA, Comparator.reverseOrder())
             *             .thenComparing(SortTest::getB, Comparator.reverseOrder())
             *             .thenComparing(SortTest::getC));
             */
            list = list.stream().sorted(Comparator.comparing(ConsumerTeamVo::getTotalPunch, Comparator.reverseOrder())).collect(Collectors.toList());

            //设置上次排名
//            for (ConsumerTeamVo item : list) {
//                if (ObjUtil.equal(item.getId(), myTeamId)) {
//                    item.setLastTop(redisCache.getCacheObject(CacheConstants.TEAM_TOP_KEY + dto.getUserId()));
//                }
//                //为空时排名设置排名默认 -1
//                if (ObjUtil.isNull(item.getLastTop())) {
//                    item.setLastTop(-1);
//                }
//            }
//            if (ObjUtil.isNotNull(myTeamId)) {
//                //排名
//                int indexOf = list.stream().map(ConsumerTeamVo::getId).collect(Collectors.toList()).indexOf(myTeamId) + 1;
//                redisCache.setCacheObject(CacheConstants.TEAM_TOP_KEY + dto.getUserId(), indexOf, 7, TimeUnit.DAYS);
//            }
        }
        return R.ok(list);
    }

    public List<Long> friendIdsList(ConsumerTeamDto dto) {
        QueryWrapper<ConsumerFriends> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", dto.getUserId());
        List<ConsumerFriends> list = consumerFriendsService.list(wrapper);
        if (CollUtil.isEmpty(list)) {
            list = new ArrayList<>();
        }
        return list.stream().map(ConsumerFriends::getFriendUserId).collect(Collectors.toList());
    }

    @Transactional(rollbackFor = Exception.class)
    public R quit(Integer teamId, Long userId) {
        //获取队伍信息
        ConsumerTeam consumerTeam = consumerTeamMapper.selectById(teamId);
        if (ObjUtil.isNull(consumerTeam)) {
            return R.fail("队伍不存在");
        }
        //执行退出队伍相关逻辑
        actionLogoutTeam(
                teamId,
                userId,
                consumerTeam.getCreateUserId(),
                "已退出" + consumerTeam.getName() + "的队伍",
                SecurityUtils.getNickName(),
                InteractMsgEnum.TEAM_QUIT
        );
        return R.ok();
    }

    /**
     * 执行退出队伍相关逻辑
     *
     * @param teamId 队伍id
     * @param userId 退出队伍的用户id
     * @param createUserId 创建队伍的用户id
     * @param message 消息类容
     * @param nickName 退出队伍的用户昵称
     * @param msgEnum 消息类型
     */
    @Transactional(rollbackFor = Exception.class)
    public void actionLogoutTeam(Integer teamId, Long userId, Long createUserId,String message,String nickName,InteractMsgEnum msgEnum) {
        //执行退出队伍逻辑
        logoutTeam(teamId, userId);

        //如果退出队伍是队长，则选一个最先加入队伍的成员作为管理员，若没有成员则解散队伍；并存储队伍消息记录
        ConsumerTeamMsgRecord msgRecord = saveConsumerTeamMsgRecord(nickName, teamId, userId, createUserId);

        //记录互动消息;站内信V23.9.7 退出队伍
        saveConsumerInteractMsg(nickName, createUserId, msgRecord.getId(),msgEnum);

        //队伍拥有者
        SocketUtil.sendOneMessage(String.valueOf(createUserId), nickName + msgEnum.getMsg(), msgEnum.getValue(), Long.valueOf(msgRecord.getId()));

        //退出方
        SocketUtil.sendOneMessage(String.valueOf(userId), message, msgEnum.getValue(), null);
    }

    /**
     * 记录互动消息
     * @param nickName 退出队伍的用户昵称
     * @param createUserId 创建队伍的用户id
     * @param msgRecordId 队伍消息记录id
     * @param msgEnum 消息类型
     */
    public void saveConsumerInteractMsg(String nickName,Long createUserId, Integer msgRecordId,InteractMsgEnum msgEnum) {
        ConsumerInteractMsg msg = new ConsumerInteractMsg();
        msg.setUserId(createUserId);//管理员收到成员退出的消息
        msg.setContent(nickName + msgEnum.getMsg());
        msg.setSourceId(Long.valueOf(msgRecordId));
        msg.setType(msgEnum);
        consumerInteractMsgService.save(msg);
    }

    /**
     * 如果退出队伍是队长，则选一个最先加入队伍的成员作为管理员，若没有成员则解散队伍；并存储队伍消息记录
     *
     * @param nickName 退出队伍的用户昵称
     * @param teamId 队伍id
     * @param userId 退出队伍用户id（当前用户）
     * @param createUserId 创建队伍的用户id
     * @return 存储队伍消息记录
     */
    public ConsumerTeamMsgRecord saveConsumerTeamMsgRecord(String nickName,Integer teamId, Long userId, Long createUserId) {
        ConsumerTeamMsgRecord msgRecord = new ConsumerTeamMsgRecord();
        msgRecord.setTeamId(teamId);
        msgRecord.setFromUserId(userId);
        msgRecord.setToUserId(userId);
        msgRecord.setContent(nickName + "退出队伍~");
        msgRecord.setSourceId(consumerTeamMemberMapper.getId(teamId, userId));

        if (ObjUtil.equal(userId, createUserId)) {
            QueryWrapper<ConsumerTeamMember> wq = new QueryWrapper<>();
            wq.eq("team_id", teamId);
            wq.orderByAsc("id");
            wq.last("limit 1");
            ConsumerTeamMember consumerTeamMember = consumerTeamMemberMapper.selectOne(wq);
            if (ObjUtil.isNotNull(consumerTeamMember)) {
                boolean y = consumerTeamMemberService.update(new LambdaUpdateWrapper<ConsumerTeamMember>()
                        .set(ConsumerTeamMember::getRole, 1)
                        .eq(ConsumerTeamMember::getTeamId, teamId)
                        .eq(ConsumerTeamMember::getUserId, consumerTeamMember.getUserId())
                );
                //编辑队伍创始人
                boolean b = update(new LambdaUpdateWrapper<ConsumerTeam>()
                        .set(ConsumerTeam::getCreateUserId, consumerTeamMember.getUserId())
                        .eq(ConsumerTeam::getId, teamId));
                if (!b || !y) {
                    throw new ServiceException("创建人更新失败");
                }
            } else { //解散队伍
                QueryWrapper<ConsumerTeam> wrapper = new QueryWrapper<>();
                wrapper.eq("id", teamId);
                int d = consumerTeamMapper.delete(wrapper);
                if (d!=1) {
                    throw new ServiceException("解散队伍失败");
                }
                //队伍解散后，待审核的 申请该队伍的用户 和 该队伍邀请过的用户 记为已超时
                consumerTeamApplyService.actionTimeOutWhenTeamFullOrDisBand(Integer.toUnsignedLong(teamId));
            }
            msgRecord.setType(ConsumerMsgRecordEnum.ADMINISTRATOR_ALTER.getValue());
        }else{
            msgRecord.setType(ConsumerMsgRecordEnum.MEMBER_ALTER.getValue());
        }
        boolean b = consumerTeamMsgRecordService.save(msgRecord);
        if (!b) {
            throw new ServiceException("添加队伍聊天记录失败");
        }
        return msgRecord;
    }

    /**
     * 推出队伍，队伍成员数量减少1
     *
     * @param teamId 队伍id
     * @param userId 用户id
     */
    public void logoutTeam(Integer teamId, Long userId) {
        boolean res = consumerTeamMemberService.update(new LambdaUpdateWrapper<ConsumerTeamMember>()
                .set(ConsumerTeamMember::getExitTime, LocalDateUtils.getCurrentLocalDateTime())
                .set(ConsumerTeamMember::getDelFlag, 1)
                .eq(ConsumerTeamMember::getTeamId, teamId)
                .eq(ConsumerTeamMember::getUserId, userId)
        );
        int i = consumerTeamMapper.abatementMemberCount(teamId, 1);
        if (!res || i != 1) {
            throw new ServiceException("退出失败");
        }
    }

    @RedisLock(lockKey = LockKey.LOCK_PUNCH_UPVOTE_LOVE)
    @Transactional(rollbackFor = Exception.class)
    public R punchUpvoteLove(ConsumerTeamMsgRecordDto params) {
        if (ObjUtil.isEmpty(params) || ObjUtil.isNull(params.getAcceptUserId())) {
            return R.fail("参数错误");
        }
        BigDecimal integral = sysConfigService.getValue(Config.Sys.Punch.提醒打卡点赞送爱心扣减数值);
        switch (params.getType()) {
            case WARN_PUNCH:
                //比较当前被提醒人的今日打卡次数 是否 等于单人当日可打卡次数
                Integer singlePunchNumber = sysConfigService.getValue(Config.Sys.Team.单人当日可打卡次数);
                Integer todayPunchNumber = (int)punchUserRecordService.countTodayPunchUser(params.getTeamId(),params.getAcceptUserId(),LocalDate.now());
                if (Objects.equals(singlePunchNumber, todayPunchNumber)) {
                    return R.fail("当前成员已完成今日打卡");
                }
                ConsumerWarnPunchRecord warnPunchRecord = new ConsumerWarnPunchRecord();
                warnPunchRecord.setWarnUserId(params.getUserId());
                warnPunchRecord.setTeamId(params.getTeamId());
                warnPunchRecord.setReceiveUserId(params.getAcceptUserId());
                warnPunchRecord.setConsumeIntegral(integral);
                warnPunchRecord.setRemarks(params.getType().getMsg());
                consumerWarnPunchRecordMapper.insert(warnPunchRecord);
                consumerTeamMsgRecordService.insertByType(params.getTeamId(), params.getType(), params.getUserId(), params.getAcceptUserId(), Long.valueOf(warnPunchRecord.getId()));
                //减积分
                sysUserWalletService.reduce(params.getUserId(), UserWalletEnum.INTEGRAL, integral, WalletChangeTypeEnum.WARN_PUNCH, Long.valueOf(warnPunchRecord.getId()), params.getType().getMsg());

                //站内信V23.9.7 提醒打卡
                ConsumerInteractMsg msg = new ConsumerInteractMsg();
                msg.setUserId(params.getAcceptUserId());
                msg.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_PUNCH.getMsg());
                msg.setSourceId(Long.valueOf(params.getTeamId()));
                msg.setType(InteractMsgEnum.TEAM_PUNCH);
                consumerInteractMsgService.save(msg);
                //被提醒方
                SocketUtil.sendOneMessage(String.valueOf(params.getAcceptUserId()), SecurityUtils.getNickName() + InteractMsgEnum.TEAM_PUNCH.getMsg(), InteractMsgEnum.TEAM_PUNCH.getValue(), Long.valueOf(params.getTeamId()));
                //提醒方
                String reminderMsg = "已提醒好友打卡~";
                ConsumerTeamMemberReminderVo vo = consumerTeamMemberService.teamMemberReminderInfo(Integer.toUnsignedLong(params.getTeamId()), params.getUserId(), params.getAcceptUserId());
                if (ObjUtil.isNotNull(vo)) {
                    String nickName = vo.getNickName();
                    if (0==vo.getParentId()) {
                        reminderMsg = StringUtils.format("已提醒\"{}\"喝水~", nickName);
                    }
                    else if (Objects.equals(params.getUserId(),vo.getParentId())) {
                        String relativeName = ConsumerTeamMemberTypeEnum.getRelativeName(vo.getReminderSex(), vo.getType());
                        reminderMsg = StringUtils.format("已提醒我的{}\"{}\"喝水~",relativeName, nickName);
                    }else {
                        ConsumerTeamMemberReminderVo vo1 = consumerTeamMemberService.teamMemberReminderInfo(Integer.toUnsignedLong(params.getTeamId()), vo.getParentId(), vo.getParentId());
                        if (ObjUtil.isNotNull(vo1)) {
                            nickName =  vo1.getNickName();
                            String relativeName = ConsumerTeamMemberTypeEnum.getRelativeName(vo1.getReminderSex(), vo.getType());
                            reminderMsg = StringUtils.format("已提醒\"{}\"的{}喝水~",nickName, relativeName);
                        }
                    }
                }
                SocketUtil.sendOneMessage(String.valueOf(params.getUserId()), reminderMsg+",+"+integral, InteractMsgEnum.TEAM_PUNCH.getValue(), Long.valueOf(params.getTeamId()));
                // 发送push推送
                pushService.pushAlertPunchMsg(params.getAcceptUserId(), SecurityUtils.getNickName());
                break;

            case SEND_LOVE:
            case UPVOTE:
                if (ObjUtil.isNull(params.getSourceId())) {
                    return R.fail("源id不能为空");
                }
                ConsumerUpvoteRecord upvoteRecord = new ConsumerUpvoteRecord();
                upvoteRecord.setPunchId(params.getSourceId());
                upvoteRecord.setType(params.getType().getValue() == 4 ? 1 : 2);
                upvoteRecord.setInitUserId(params.getUserId());
                upvoteRecord.setConsumeIntegral(integral);
                consumerUpvoteRecordMapper.insert(upvoteRecord);
                consumerTeamMsgRecordService.insertByType(params.getTeamId(), params.getType(), params.getUserId(), params.getAcceptUserId(), params.getSourceId());
                //减积分
                sysUserWalletService.reduce(params.getUserId(), UserWalletEnum.INTEGRAL, integral, WalletChangeTypeEnum.INTERACT, Long.valueOf(upvoteRecord.getId()), params.getType().getMsg());

                //站内信V23.9.7 点赞、送爱心
                ConsumerInteractMsg ms = new ConsumerInteractMsg();
                ms.setUserId(params.getAcceptUserId());
                if (params.getType().getValue() == 4) {
                    ms.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_SUPPORT.getMsg());
                    ms.setType(InteractMsgEnum.TEAM_SUPPORT);
                } else {
                    ms.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_LOVE.getMsg());
                    ms.setType(InteractMsgEnum.TEAM_LOVE);
                }
                ms.setSourceId(Long.valueOf(params.getTeamId()));
                consumerInteractMsgService.save(ms);
                //被提醒方
                SysUser acceptUser = sysUserService.selectUserById(params.getAcceptUserId());
                SocketUtil.sendOneMessage(String.valueOf(params.getAcceptUserId()), SecurityUtils.getNickName() + ",+" + SecurityUtils.getAvatar() + ",+" + SecurityUtils.getUserId(), params.getType().getValue() == 4 ? InteractMsgEnum.TEAM_SUPPORT.getValue() : InteractMsgEnum.TEAM_LOVE.getValue(), Long.valueOf(params.getTeamId()));
                //提醒方
                SocketUtil.sendOneMessage(String.valueOf(params.getUserId()), acceptUser.getNickName() + ",+" + acceptUser.getAvatar() + ",+" + acceptUser.getUserId(), params.getType().getValue() == 4 ? InteractMsgEnum.TEAM_SUPPORT.getValue() : InteractMsgEnum.TEAM_LOVE.getValue(), Long.valueOf(params.getTeamId()));
                break;

            default:
                return R.fail("类型错误");
        }
        return R.ok();
    }


    /**
     *  v1.6.0 主成员点击【加入】按钮，弹出快捷加入弹窗，家庭其他成员点击【加入】按钮提示：家属不能加入其他队伍
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public R joinTeam(ConsumerTeamMsgRecordDto dto) {
        ConsumerTeam team = consumerTeamMapper.selectById(dto.getTeamId());
        if (ObjUtil.isNull(team)) {
            return R.fail("队伍已经解散啦~");
        }
        if (team.getMemberCount() >= team.getMaxNumber()) {
            return R.fail("队伍已满员，无法加入");
        }
        LambdaQueryWrapper<ConsumerTeamMember> wq2 = new LambdaQueryWrapper<>();
//        wq2.eq(ConsumerTeamMember::getTeamId, team.getId());
        wq2.eq(ConsumerTeamMember::getUserId, dto.getUserId());
        ConsumerTeamMember member = consumerTeamMemberMapper.selectOne(wq2);
        if (ObjUtil.isNotNull(member) && member.getType()!=ConsumerTeamMemberTypeEnum.TYPE_MAIN) {
            return R.fail("家属成员不能加入其他队伍~");
        }
        if (ObjUtil.isNotNull(member)) {
            return R.fail("已经有队伍了，不能再加入啦~");
        }

        //加入队伍无需审核 直接入队(邀请亲属家庭成员也无需审核)
        if (team.getNeedVerify() == 0 || (dto.getMemberType() != null && dto.getMemberType() != ConsumerTeamMemberTypeEnum.TYPE_MAIN)) {
            ConsumerTeamMember teamMember2 = new ConsumerTeamMember();
            teamMember2.setTeamId(team.getId());
            teamMember2.setRole(ConsumerTeamRoleEnum.ORDINARY_MEMBER.getValue());
            teamMember2.setJoinTime(LocalDateUtils.getCurrentLocalDateTime());
            teamMember2.setUserId(dto.getUserId());
            //家庭成员
            if (dto.getMemberType() != null) {
                teamMember2.setType(dto.getMemberType());
                teamMember2.setParentId(dto.getMemberType() == ConsumerTeamMemberTypeEnum.TYPE_MAIN ? 0 : dto.getInviteId());
            }
//            teamMember2.setInviteUserId(dto.getInviteUserId());
            //队伍消息记录已读位置id
            teamMember2.setTeamMsgId(consumerTeamMsgRecordService.findLastId());
            boolean x = consumerTeamMemberService.save(teamMember2);
            int y = consumerTeamMapper.addMemberCount(team.getId(), 1);
            //添加队伍消息记录
            ConsumerTeamMsgRecord msg = new ConsumerTeamMsgRecord();
            msg.setType(ConsumerMsgRecordEnum.MEMBER_ALTER.getValue());
            msg.setTeamId(team.getId());
            msg.setFromUserId(dto.getUserId());
            msg.setToUserId(dto.getUserId());
            msg.setContent(SecurityUtils.getNickName() + "加入~");
            msg.setSourceId(Long.valueOf(teamMember2.getId()));
            boolean s = consumerTeamMsgRecordService.save(msg);
            if (!s || !x || y != 1) {
                throw new ServiceException("处理加入队伍失败");
            }
            //刷新队伍打卡次数
            refreshPunchGain(Long.valueOf(dto.getTeamId()));
            //其它待审核的申请 和 邀请我的记录 记为已超时
            consumerTeamApplyService.actionTimeOutWhenJoinTeam(dto.getUserId());
            //队伍满员后，待审核的 申请该队伍的用户 和 该队伍邀请过的用户 记为已超时
            if (team.getMemberCount()+1 >= team.getMaxNumber()) {
                consumerTeamApplyService.actionTimeOutWhenTeamFullOrDisBand(Integer.toUnsignedLong(dto.getTeamId()));
            }
            return R.ok_msg( "成功加入队伍");
        }

        LambdaQueryWrapper<ConsumerTeamApply> wr = new LambdaQueryWrapper<>();
        wr.eq(ConsumerTeamApply::getTeamId, dto.getTeamId());
        wr.eq(ConsumerTeamApply::getUserId, dto.getUserId());
        wr.eq(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.PENDING.getValue());
        long count = consumerTeamApplyService.count(wr);
        if (ObjUtil.isNotNull(count) && count > 0) {
            consumerTeamApplyService.update(new LambdaUpdateWrapper<ConsumerTeamApply>()
                    .set(ConsumerTeamApply::getCreateTime, LocalDateUtils.getCurrentLocalDateTime())
                    .eq(ConsumerTeamApply::getTeamId, dto.getTeamId())
                    .eq(ConsumerTeamApply::getUserId, dto.getUserId())
                    .eq(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.PENDING.getValue())
            );
            return R.ok_msg( "已发送加入申请");
        }

//        LambdaQueryWrapper<ConsumerTeamMember> wq = new LambdaQueryWrapper<>();
//        wq.eq(ConsumerTeamMember::getTeamId, dto.getTeamId());
//        wq.eq(ConsumerTeamMember::getRole, ConsumerTeamRoleEnum.ADMINISTRATOR.getValue());
//        ConsumerTeamMember teamMember = consumerTeamMemberMapper.selectOne(wq);

        ConsumerTeamApply apply = new ConsumerTeamApply();
        apply.setTeamId(dto.getTeamId());
        apply.setType(dto.getApplyTypeEnum().getValue());
        apply.setUserId(dto.getUserId());
        apply.setStatus(ConsumerApplyStatusEnum.PENDING.getValue());
        apply.setHandlerUserId(team.getCreateUserId());
        apply.setInviteId(dto.getInviteId());
        apply.setMemberType(dto.getMemberType());
        consumerTeamApplyService.save(apply);

        //站内信V23.9.7 加入队伍
        ConsumerInteractMsg msg = new ConsumerInteractMsg();
        msg.setUserId(team.getCreateUserId());//管理员收到申请消息
        msg.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_ADD.getMsg());
        msg.setSourceId(Long.valueOf(apply.getId()));
        msg.setType(InteractMsgEnum.TEAM_ADD);
        consumerInteractMsgService.save(msg);

        SocketUtil.sendOneMessage(String.valueOf(team.getCreateUserId()), SecurityUtils.getNickName() + InteractMsgEnum.TEAM_ADD.getMsg(), InteractMsgEnum.TEAM_ADD.getValue(), Long.valueOf(apply.getId()));
        return R.ok_msg( "已发送申请，请等待审核");
    }

    public R inviteJoinTeam(ConsumerTeamMsgRecordDto dto) {
        ConsumerTeam team = consumerTeamMapper.selectById(dto.getTeamId());
        if (ObjUtil.isNull(team)) {
            return R.fail("队伍已经解散啦~");
        }

        LambdaQueryWrapper<ConsumerTeamMember> wq = new LambdaQueryWrapper<>();
        wq.eq(ConsumerTeamMember::getTeamId, team.getId());
        wq.eq(ConsumerTeamMember::getUserId, dto.getUserId());
        ConsumerTeamMember teamMember = consumerTeamMemberMapper.selectOne(wq);
        if (ObjUtil.isNull(teamMember)) {
            return R.fail("成员不存在");
        }
        if (ObjUtil.notEqual(teamMember.getRole(), ConsumerTeamRoleEnum.ADMINISTRATOR.getValue())) {
            return R.fail("您不是当前队伍管理员~");
        }

        if (CollUtil.isNotEmpty(dto.getInviteUserId())) {
            ArrayList<ConsumerTeamApply> list = new ArrayList<>();
            ArrayList<ConsumerInteractMsg> msgs = new ArrayList<>();
            LambdaQueryWrapper<ConsumerTeamApply> wpApply = new LambdaQueryWrapper<>();

            dto.getInviteUserId().forEach(item -> {
                wpApply.eq(ConsumerTeamApply::getTeamId, team.getId());
                wpApply.eq(ConsumerTeamApply::getType, ConsumerApplyTypeEnum.ADMINISTRATOR_INVITATION.getValue());
                wpApply.eq(ConsumerTeamApply::getUserId, dto.getUserId());
                wpApply.eq(ConsumerTeamApply::getStatus, ConsumerApplyStatusEnum.PENDING.getValue());
                wpApply.eq(ConsumerTeamApply::getHandlerUserId, item);
                wpApply.last("limit 1");
                ConsumerTeamApply one = consumerTeamApplyService.getOne(wpApply);
                if (ObjUtil.isNull(one)) {
                    ConsumerTeamApply apply = new ConsumerTeamApply();
                    apply.setTeamId(team.getId());
                    apply.setType(ConsumerApplyTypeEnum.ADMINISTRATOR_INVITATION.getValue());
                    apply.setUserId(dto.getUserId());//管理员邀请userid
                    apply.setStatus(ConsumerApplyStatusEnum.PENDING.getValue());
                    apply.setHandlerUserId(item);
                    list.add(apply);

                    //站内信V23.9.7 邀请好友加入队伍
                    ConsumerInteractMsg msg = new ConsumerInteractMsg();
                    msg.setUserId(item);//被邀请人收到邀请消息
                    msg.setContent(SecurityUtils.getNickName() + InteractMsgEnum.TEAM_INVITE.getMsg());
//                    msg.setSourceId(Long.valueOf(apply.getId()));//批量插入暂无申请源id
                    msg.setType(InteractMsgEnum.TEAM_INVITE);
                    msgs.add(msg);

                    SocketUtil.sendOneMessage(String.valueOf(item), SecurityUtils.getNickName() + InteractMsgEnum.TEAM_INVITE.getMsg(), InteractMsgEnum.TEAM_INVITE.getValue(), null);
                }
            });
            if (CollUtil.isNotEmpty(list)) {
                consumerTeamApplyService.saveBatch(list);
                consumerInteractMsgService.saveBatch(msgs);
            }
        }
        return R.ok();
    }

    public List<ConsumerTeamVo> selectList(ConsumerTeamDto dto) {
        return consumerTeamMapper.selectListVo(dto);
    }

    public R<TeamCheckRecordVo> info(Integer teamId) {
        ConsumerTeam team = this.getById(teamId);
        if (ObjUtil.isNull(team)) {
            return R.fail("队伍不存在");
        }

        LambdaQueryWrapper<ConsumerTeamMember> wq = new LambdaQueryWrapper<>();
        wq.eq(ConsumerTeamMember::getTeamId, teamId);
        wq.orderByDesc(ConsumerTeamMember::getCreateTime);
        List<ConsumerTeamMember> memberList = consumerTeamMemberService.list(wq);
//        List<TeamPunchRecordVo> punchRecord = consumerTeamMapper.selectPunchRecord(teamId);
        LambdaQueryWrapper<TeamPunchStat> wp = new LambdaQueryWrapper<>();
        // 设置日期条件
        LocalDateTime startDate = LocalDateTime.now().minusDays(30);
        wp.eq(TeamPunchStat::getTeamId, teamId);
        wp.ge(TeamPunchStat::getCreateTime, startDate);
        wp.le(TeamPunchStat::getCreateTime, LocalDateTime.now());
        wp.orderByDesc(TeamPunchStat::getCreateTime);
        List<TeamPunchStat> punchList = teamPunchStatService.list(wp);


        TeamCheckRecordVo vo = BeanUtil.copyProperties(team, TeamCheckRecordVo.class);
        vo.setTeamGain(team.getMemberGain());
        vo.setMemberList(memberList);
        vo.setPunchRecord(BeanUtil.copyToList(punchList, TeamPunchRecordVo.class));
        return R.ok(vo);
    }

    /**
     * 刷新队伍打卡增益
     *
     * @param teamId
     */
    @Transactional(rollbackFor = Exception.class)
    public void refreshPunchGain(Long teamId) {
        if (Objects.nonNull(teamId)) {
            long todayPunchCount = userRecordService.countTeamTodayPunchNew(teamId, LocalDate.now());
            long totalPunchCount = userRecordService.countTeamTotalPunch(teamId);
            //判断满足哪个阶段， 更新队伍打卡增益
            Integer teamRank = getTeamRankByTeamId(teamId); //队伍排名为空（队伍不存在，可能在退出队伍时为队长，就解散了）
            BigDecimal punchGain = BigDecimal.ZERO;
            if (teamRank!=null) {//说明该队伍还存在，进行更新
                ConsumerTeamGainRule punchCountRule = teamGainRuleService.getPunchCountRule(todayPunchCount,teamRank);
                if (Objects.nonNull(punchCountRule)) {
                    punchGain = punchCountRule.getGain();
                }
                update(new LambdaUpdateWrapper<ConsumerTeam>()
                        .eq(ConsumerTeam::getId, teamId)
                        .set(ConsumerTeam::getTodayPunchCount, todayPunchCount)
                        .set(ConsumerTeam::getTotalPunchCount, totalPunchCount)
                        .set(ConsumerTeam::getMemberGain, punchGain));
            }
        }
    }

    /**
     * 获取我的队伍
     *
     * @param userId
     * @return
     */
    public ConsumerTeamVo getMyTeam(Long userId) {
        //获取我的队伍信息
        return consumerTeamMapper.getMyTeam(userId);
    }

    /**
     * 获取当前用户（队长|成员）的队伍等级
     *
     * @param teamId 队伍id
     * @param userId 用户id
     * @return 队伍等级
     */
    public ConsumerTeamVo getCurrentUserTeam(Long teamId,Long userId){
        ConsumerTeamVo vo = getCurrentUserTeamOrGetNull(teamId,userId);
        if(vo==null){
            throw new ServiceException("非队伍管理员（队长），不能进行队伍升级!");
        }
        return vo;
    }
    public ConsumerTeamVo getCurrentUserTeamOrGetNull(Long teamId,Long userId){
        ConsumerTeamVo vo = consumerTeamMapper.getCurrentUserTeamRank(teamId,userId);
        return Optional.ofNullable(vo).orElse(null);
    }


    /**
     *
     * 获取队伍等级by队伍id
     *
     * @param teamId 队伍id
     * @return 队伍等级
     */
    public Integer getTeamRankByTeamId(Long teamId){
        ConsumerTeam team = this.lambdaQuery().select(ConsumerTeam::getRank).eq(ConsumerTeam::getId, teamId).one();
        return ObjUtil.isNull(team)?null:team.getRank();
    }

    /**
     * 清空所有队伍的打卡增益数据
     */
    public void cleanTeamPunchGain() {
        baseMapper.cleanTeamPunchGain();
    }

    /**
     * 统计队伍打卡增益
     */
    public void statTeamPunch(LocalDate date) {
        int page = 1, size = 100;
        while (true) {
            PageHelper.startPage(page, size);
            List<ConsumerTeam> teamList = list();
            // 统计数据
            List<TeamPunchStat> statList = new ArrayList<>();
            for (ConsumerTeam team : teamList) {
                // 判断团队今日是否已经统计？
                boolean todayStat = teamPunchStatService.isTodayStat(team.getId(), date);
                if (!todayStat) {
                    // 如果没有统计再插入数据
                    TeamPunchStat stat = buildTeamPunchStat(team.getId(), date);
                    statList.add(stat);
                }
            }
            teamPunchStatService.saveBatch(statList);
            if (teamList.size() < size) {
                return;
            }
            page++;
        }
    }

    /**
     * 构建团队打卡统计信息
     *
     * @param teamId
     * @param date   统计日期
     * @return
     */
    private TeamPunchStat buildTeamPunchStat(Integer teamId, LocalDate date) {
        TeamPunchStat stat = new TeamPunchStat();
        stat.setStatDate(date);
        stat.setTeamId(teamId);
        stat.setIsSettle(false);

        long punchCount = userRecordService.countTeamTodayPunchNew(Long.valueOf(teamId), date);
        //判断满足哪个阶段， 更新队伍打卡增益
        Integer teamRank = getTeamRankByTeamId(Long.valueOf(teamId));
        BigDecimal punchGain = BigDecimal.ZERO;
        if (teamRank!=null) {
            ConsumerTeamGainRule punchCountRule = teamGainRuleService.getPunchCountRule(punchCount,teamRank);
            if (Objects.nonNull(punchCountRule)) {
                punchGain = punchCountRule.getGain();
            }
        }

        stat.setPunchCount((int) punchCount);
        stat.setMemberGain(punchGain);
        stat.setPunchUserCount(userRecordService.countTeamTodayPunchUser(Long.valueOf(teamId), date));
        return stat;
    }


    /**
     * 获取我的队伍排行信息
     * TODO 先简单做：直接获取所有队伍进行排名处理，因为前期队伍少，数据处理还好
     * TODO 后期优化：队伍多了之后这了肯定耗时多，因此应该修改排行逻辑，只有打卡的才参与排行，比如微信步数，这个排行榜可以存放到redis->zset进行处理，这样操作也简单
     *
     * @param userId 用户ID
     * @return
     */
    public ConsumerTeamRankVo getMyTeamRank(Long userId) {
        ConsumerTeamRankVo result = new ConsumerTeamRankVo();
        ConsumerTeamVo myTeam = getMyTeam(userId);
        if (Objects.nonNull(myTeam)) {
            result.setTeamInfo(myTeam);
            // 只有自己有队伍才获取其他信息
            // 获取打卡增益规则
            List<ConsumerTeamGainRule> ruleList = teamGainRuleService.getConsumerTeamGainRules(myTeam.getRank());
            result.setGainRuleList(ruleList);

            // 获取我在该队伍的今日打卡收益
            BigDecimal todayIncome = punchUserRecordService.getUserTotalIncome(userId, myTeam.getId(), LocalDate.now());

            // 判断队伍当前的打卡增益
            ConsumerTeamGainRule currentGain = ruleList.stream().filter(rule -> rule.getTotalPunch() <= myTeam.getTotalPunch()).reduce((first, second) -> second).orElse(null);
            if (currentGain != null) {
                TeamGainInfoVo gainVo = new TeamGainInfoVo();
                gainVo.setGain(currentGain.getGain());
                gainVo.setLackPunchCount(0);
                gainVo.setPunchCount(currentGain.getTotalPunch());
                gainVo.setIncome(todayIncome.multiply(gainVo.getGain()).setScale(2, RoundingMode.UP));
                result.setCurrentGainInfo(gainVo);
            }

            // 计算队伍下阶段的打卡增益
            ConsumerTeamGainRule nextGain = ruleList.stream().filter(rule -> rule.getTotalPunch() > myTeam.getTotalPunch()).findFirst().orElse(null);
            if (nextGain != null) {
                if (todayIncome.compareTo(BigDecimal.ZERO) <= 0) {
                    // 用户今日在该队伍还没有收益，则以用户下次预估收益为基础去计算
                    PunchUserConfig config = punchUserConfigService.getConfig(userId);
                    if (config.getNftNumberId() != null) {
                        Equipment equipment = equipmentService.getByNftNumberId(config.getNftNumberId());
                        if (Objects.nonNull(equipment)) {
                            BigDecimal nextIncome = userPunchService.calcPunchIncome(equipment, true);
                            // 判断日收益上限
                            BigDecimal dayIncomeMax = sysConfigService.getValue(Config.Sys.Punch.日打卡收益上限);
                            if (Objects.nonNull(dayIncomeMax)) {
                                // 如果设置了打卡上限
                                if (LocalDateTimeUtil.isSameDay(config.getNextPunchTime(), LocalDateTime.now())) {
                                    // 如果下次打卡是当天，则判断今日打卡是否达到上限
                                    BigDecimal subIncome = dayIncomeMax.subtract(config.getTodayPunchIncome());
                                    if (subIncome.compareTo(BigDecimal.ZERO) <= 0) {
                                        nextIncome = BigDecimal.ZERO;
                                    } else {
                                        // 如果剩余的收益额度小于打卡收益额度，则以剩余收益额度为准
                                        if (subIncome.compareTo(nextIncome) < 0) {
                                            nextIncome = subIncome;
                                        }
                                    }
                                } else {
                                    // 如果不是同一天，则判断打卡收益是否超过打卡上限
                                    if (dayIncomeMax.compareTo(nextIncome) < 0) {
                                        nextIncome = dayIncomeMax;
                                    }
                                }
                            }
                            // 将下次预估收益设置到今日收益去计算
                            todayIncome = nextIncome;
                        }
                    }
                }

                TeamGainInfoVo gainVo = new TeamGainInfoVo();
                gainVo.setGain(nextGain.getGain());
                gainVo.setPunchCount(nextGain.getTotalPunch());
                gainVo.setLackPunchCount(gainVo.getPunchCount() - myTeam.getTotalPunch());
                gainVo.setIncome(todayIncome.multiply(gainVo.getGain()).setScale(2, RoundingMode.UP));
                result.setNextGainInfo(gainVo);
            }

            // 获取队伍排名
            List<Long> rankList = list(new LambdaQueryWrapper<ConsumerTeam>()
                    .select(ConsumerTeam::getId)
                    .orderByDesc(ConsumerTeam::getTodayPunchCount)
                    .orderByAsc(ConsumerTeam::getId))
                    .stream().map(team -> (long) team.getId()).collect(Collectors.toList());

            // 获取队伍上次排名信息
            Integer lastRank = redisCache.getCacheObject(CacheConstants.TEAM_TOP_KEY + userId);
            if (lastRank == null) {
                lastRank = -1;
            }
            result.setLastRank(lastRank);
            // 获取队伍当前的排名信息
            int currentRank = rankList.indexOf(myTeam.getId()) + 1;
            result.setCurrentRank(currentRank);
            // 获取队伍当前排名的上下队伍
            if (currentRank < rankList.size()) {
                Long behindTeamId = rankList.get(currentRank);
                ConsumerTeamVo behindTeamVo = getBaseMapper().getTeamInfo(behindTeamId);
                result.setBehindTeamInfo(behindTeamVo);
            }
            // 记录本次队伍排名信息
            redisCache.setCacheObject(CacheConstants.TEAM_TOP_KEY + userId, currentRank, 7, TimeUnit.DAYS);
        }
        return result;
    }

    /**
     * 删除队伍成员
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public R deleteMemberByUserIds(ConsumerTeamDelDto dto) {
        Long userId = SecurityUtils.getUserId();
        //查询操作人有无编辑权限
        ConsumerTeamMember teamMember = consumerTeamMemberService.getOne(new LambdaQueryWrapper<ConsumerTeamMember>()
                .eq(ConsumerTeamMember::getTeamId, dto.getId())
                .eq(ConsumerTeamMember::getUserId, userId));
        if (!teamMember.getRole().equals(ConsumerTeamRoleEnum.ADMINISTRATOR.getValue())) {
            return R.fail("无权限修改");
        }

        boolean b = consumerTeamMemberService.update(new LambdaUpdateWrapper<ConsumerTeamMember>()
                .set(ConsumerTeamMember::getExitTime, LocalDateUtils.getCurrentLocalDateTime())
                .set(ConsumerTeamMember::getDelFlag, 1)
                .eq(ConsumerTeamMember::getTeamId, dto.getId())
                .in(ConsumerTeamMember::getUserId, dto.getTeamMemberIds())
        );
        if (!b) {
            throw new ServiceException("删除成员失败");
        }
        int num = consumerTeamMapper.abatementMemberCount(dto.getId(), dto.getTeamMemberIds().size());
        if (num != 1) {
            throw new ServiceException("删除队伍成员人数失败");
        }

        return R.ok();
    }


    /**
     * 修改队伍等级 和 最大成员数量
     *
     * @param teamId 队伍id
     * @param upgradeRank 队伍等级
     * @param upgradeNumber 最大成员数量
     */
    @Transactional
    public void updateRankAndMaxMember(Long teamId, Integer upgradeRank, Integer upgradeNumber) {
        boolean update = this.lambdaUpdate()
                .set(ConsumerTeam::getRank, upgradeRank)
                .set(ConsumerTeam::getMaxNumber, upgradeNumber)
                .eq(ConsumerTeam::getId, teamId)
                .update();
        if (!update) {
            throw new ServiceException("修改队伍等级和最大成员数量失败!");
        }
    }
}